package com.cnswhy.cloud.server.core.channel.wxpay.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cnswhy.cloud.common.core.exception.BizException;
import com.cnswhy.cloud.server.core.channel.verify.util.HttpUtils;
import com.cnswhy.cloud.server.core.channel.wxpay.model.WxSessionKeyReq;
import com.cnswhy.cloud.server.core.channel.wxpay.model.WxSessionKeyRp;
import com.cnswhy.cloud.server.core.channel.wxpay.model.WxpayServiceRp;
import com.cnswhy.cloud.server.core.channel.wxpay.service.WxpayService;
import com.cnswhy.cloud.server.core.channel.wxpay.utils.HttpUtil;
import com.cnswhy.cloud.server.core.channel.wxpay.utils.PayCommonUtil;
import com.cnswhy.cloud.server.core.channel.wxpay.utils.PayConfig;
import com.cnswhy.cloud.server.core.channel.wxpay.utils.XMLUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

@Service
@Slf4j
public class WxpayServiceImpl implements WxpayService {


    private String APP_ID = PayConfig.APP_ID;

    private String MCH_ID = PayConfig.MCH_ID;

    private String APP_KEY = PayConfig.API_KEY;

    private String PAY_URL = PayConfig.PAY_URL;

    private String NOTIFY_URL = PayConfig.NOTIFY_URL;

    private String DF_QUERY_URL = PayConfig.ORDERDFQUERY;

    @Override
    public WxpayServiceRp queryOrder(String out_trade_no) throws Exception {
        WxpayServiceRp wxpayServiceRp = new WxpayServiceRp();
        // ip地址获取
        // 账号信息
        String currTime = PayCommonUtil.getCurrTime();
        String strTime = currTime.substring(8, currTime.length());
        String strRandom = PayCommonUtil.buildRandom(4) + "";
        String nonce_str = strTime + strRandom;
        // 设置package订单参数
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        packageParams.put("appid", APP_ID);
        packageParams.put("mch_id", MCH_ID);
        // 生成签名的时候需要你自己设置随机字符串
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("out_trade_no", out_trade_no);
        String sign = PayCommonUtil.createSign("UTF-8", packageParams, APP_KEY);
        packageParams.put("sign", sign);
        log.info("微信支付查询请求参数=appid={}，mch_id={}，nonce_str={}，out_trade_no={} ,sign={}", APP_ID, MCH_ID, nonce_str, out_trade_no, sign);

        String requestXML = PayCommonUtil.getRequestXml(packageParams);
        log.info("微信支付请求参数=requestXML=[{}]", requestXML);
        String resXml = HttpUtil.postData("https://api.mch.weixin.qq.com/pay/orderquery", requestXML);
        Map map = XMLUtil.doXMLParse(resXml);
        log.info("微信支付返回参数=resXml=[{}]", resXml);

        if (StringUtils.isNotEmpty(map.get("return_code").toString()) && map.get("return_code").toString().equals("SUCCESS")) {
            if (StringUtils.isNotEmpty(map.get("result_code").toString()) && map.get("result_code").toString().equals("SUCCESS")) {
                if (StringUtils.isNotEmpty(map.get("trade_state").toString()) && map.get("trade_state").toString().equals("SUCCESS")) {
                    wxpayServiceRp.setResult_code("0000");
                    wxpayServiceRp.setResult_msg("交易成功");
                } else if (StringUtils.isNotEmpty(map.get("trade_state").toString()) && map.get("trade_state").toString().equals("NOTPAY")) {
                    wxpayServiceRp.setResult_code("0100");
                    wxpayServiceRp.setResult_msg(map.get("trade_state_desc").toString());
                } else if (StringUtils.isNotEmpty(map.get("trade_state").toString()) && map.get("trade_state").toString().equals("PAYERROR")) {
                    wxpayServiceRp.setResult_code("0001");
                    wxpayServiceRp.setResult_msg(map.get("trade_state_desc").toString());
                } else {
                    wxpayServiceRp.setResult_code("0100");
                    wxpayServiceRp.setResult_msg(map.get("trade_state_desc").toString());
                }
            } else if (StringUtils.isNotEmpty(map.get("result_code").toString()) && map.get("result_code").toString().equals("FAIL")) {
                wxpayServiceRp.setResult_code("0001");
                wxpayServiceRp.setResult_msg(map.get("err_code_des").toString());
            } else {
                wxpayServiceRp.setResult_code("0001");
                wxpayServiceRp.setResult_msg(map.get("err_code_des").toString());
            }

        } else if (StringUtils.isNotEmpty(map.get("return_code").toString()) && map.get("return_code").toString().equals("FAIL")) {
            wxpayServiceRp.setResult_code("0100");
            wxpayServiceRp.setResult_msg(map.get("return_msg").toString());
        } else {
            wxpayServiceRp.setResult_code("0100");
            wxpayServiceRp.setResult_msg("查询异常");
        }
        log.info("微信支付查询返回参数=Result_code={}，Result_msg={}，out_trade_no={}", wxpayServiceRp.getResult_code(), wxpayServiceRp.getResult_msg(), out_trade_no);

        return wxpayServiceRp;
    }

    @Override
    public WxpayServiceRp toPay(String out_trade_no, Double total_amount, String spbill_create_ip, String returnUrl) throws Exception {
        WxpayServiceRp wxpayServiceRp = new WxpayServiceRp();
        try {
            // ip地址获取
            // 账号信息
            String appid = APP_ID; // appid
            String mch_id = MCH_ID; // 商业号
            String key = APP_KEY; // key
            String currTime = PayCommonUtil.getCurrTime();
            String strTime = currTime.substring(8, currTime.length());
            String strRandom = PayCommonUtil.buildRandom(4) + "";
            String nonce_str = strTime + strRandom;
            // 价格 注意：价格的单位是分
            String order_price = new BigDecimal(total_amount).multiply(new BigDecimal(100)).toString().split("\\.")[0];
            // 获取发起电脑 ip

            // 回调接口
            // 页面跳转同步通知页面路径
            String trade_type = "MWEB";

            // 设置package订单参数
            SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
            packageParams.put("appid", appid);
            packageParams.put("mch_id", mch_id);
            // 生成签名的时候需要你自己设置随机字符串
            packageParams.put("nonce_str", nonce_str);
            packageParams.put("out_trade_no", out_trade_no);
            packageParams.put("total_fee", order_price);
            packageParams.put("spbill_create_ip", spbill_create_ip);
            packageParams.put("notify_url", NOTIFY_URL);
            packageParams.put("trade_type", trade_type);
            packageParams.put("body", PayConfig.BODY);
            packageParams.put("scene_info", "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"http://jgj.hechuang8.com/\",\"wap_name\": \"VIP购买\"}}");
            String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);
            packageParams.put("sign", sign);
            log.info("微信支付请求参数=appid={}，mch_id={}，nonce_str={}，out_trade_no={} ,sign={}", appid, mch_id, nonce_str, out_trade_no, sign);
            String requestXML = PayCommonUtil.getRequestXml(packageParams);
            log.info("微信支付请求参数=requestXML=[{}]", requestXML);
            String resXml = HttpUtil.postData(PAY_URL, requestXML);
            log.info("微信支付返回参数=resXml=[{}]", resXml);

            Map map = XMLUtil.doXMLParse(resXml);
            if (StringUtils.isNotEmpty(map.get("return_code").toString()) && map.get("return_code").toString().equals("SUCCESS")) {
                if (StringUtils.isNotEmpty(map.get("result_code").toString()) && map.get("result_code").toString().equals("SUCCESS")) {
                    String urlCode = (String) map.get("code_url");
                    //确认支付过后跳的地址,需要经过urlencode处理
                    String urlString = URLEncoder.encode(returnUrl, "GBK");
                    String mweb_url = map.get("mweb_url") + "&redirect_url=" + urlString;
                    wxpayServiceRp.setMweb_url(mweb_url);
                    wxpayServiceRp.setResult_msg("获取成功");
                    wxpayServiceRp.setResult_code("0000");
                } else {
                    wxpayServiceRp.setResult_msg(map.get("err_code_des").toString());
                    wxpayServiceRp.setResult_code("0001");
                }
            } else {
                wxpayServiceRp.setResult_msg(map.get("return_msg").toString());
                wxpayServiceRp.setResult_code("0001");
            }

        } catch (Exception e) {
            wxpayServiceRp.setResult_code("0100");
            wxpayServiceRp.setResult_msg("等待处理中");
        }
        log.info("微信支付返回参数=Result_code={}，Result_msg={}，out_trade_no={}", wxpayServiceRp.getResult_code(), wxpayServiceRp.getResult_msg(), out_trade_no);
        return wxpayServiceRp;
    }

    @Override
    public JSONObject notify(Map<String, String> map) throws BizException {
        return null;
    }

    @Override
    public WxSessionKeyRp getWxSessionKey(WxSessionKeyReq wxSessionKeyReq) {

        String host = "https://api.weixin.qq.com";
        String path = "/sns/jscode2session";
        String method = "GET";
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "authorization_code");
        Map<String, String> querys = new HashMap<String, String>();
        querys.put("appid", wxSessionKeyReq.getAppid());
        querys.put("grant_type", "authorization_code");
        querys.put("js_code", wxSessionKeyReq.getJs_code());
        querys.put("secret", wxSessionKeyReq.getSecret());
        WxSessionKeyRp wxSessionKeyRp = null;
        try {
            HttpResponse response = HttpUtils.doGet(host, path, method, headers, querys);
            String responseMsg = new String(EntityUtils.toString(response.getEntity()));
            System.out.println(responseMsg);
            wxSessionKeyRp = JSON.parseObject(responseMsg, WxSessionKeyRp.class);

            if (wxSessionKeyRp == null) {
                wxSessionKeyRp = new WxSessionKeyRp();
                wxSessionKeyRp.setErrcode("40001");
                wxSessionKeyRp.setErrmsg("网络异常");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        log.info("exit getWxSessionKey:{}", JSONObject.toJSON(wxSessionKeyRp));
        return wxSessionKeyRp;

    }

    @Override
    public WxpayServiceRp daifu(String out_trade_no, Long total_amount, String userName, String openId) throws Exception {
        WxpayServiceRp wxpayServiceRp = new WxpayServiceRp();
        try {
            // ip地址获取
            // 账号信息
            String currTime = PayCommonUtil.getCurrTime();
            String strTime = currTime.substring(8, currTime.length());
            String strRandom = PayCommonUtil.buildRandom(4) + "";
            String nonce_str = strTime + strRandom;
            // 价格 注意：价格的单位是分
            String order_price = new BigDecimal(total_amount).multiply(new BigDecimal(100)).toString().split("\\.")[0];
            // 获取发起电脑 ip

            // 设置package订单参数
            SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
            packageParams.put("mch_appid", APP_ID);
            packageParams.put("mchid", MCH_ID);
            // 生成签名的时候需要你自己设置随机字符串
            packageParams.put("nonce_str", nonce_str);
            packageParams.put("partner_trade_no", out_trade_no);
            packageParams.put("openid", openId);
            packageParams.put("check_name", "FORCE_CHECK");
            packageParams.put("re_user_name", userName);
            packageParams.put("amount", order_price);
            packageParams.put("desc", "提现");

            String sign = PayCommonUtil.createSign("UTF-8", packageParams, APP_KEY);
            packageParams.put("sign", sign);
            log.info("微信支付请求参数=appid={}，mch_id={}，nonce_str={}，out_trade_no={} ,sign={}", APP_ID, MCH_ID, nonce_str, out_trade_no, sign);
            String requestXML = PayCommonUtil.getRequestXml(packageParams);
            log.info("微信支付请求参数=requestXML=[{}]", requestXML);
            String resXml = HttpUtil.postData(PAY_URL, requestXML);
            log.info("微信支付返回参数=resXml=[{}]", resXml);

            Map map = XMLUtil.doXMLParse(resXml);
            if (StringUtils.isNotEmpty(map.get("return_code").toString())) {
                if ("SUCCESS".equals(map.get("return_code").toString())) {
                    wxpayServiceRp.setResult_msg("发起成功");
                    wxpayServiceRp.setResult_code("0100");
                } else if ("FAIL".equals("")) {
                    wxpayServiceRp.setResult_msg("发起失败");
                    wxpayServiceRp.setResult_code("0001");
                } else {
                    wxpayServiceRp.setResult_msg(map.get("err_code").toString());
                    wxpayServiceRp.setResult_code("0100");
                }
            } else {
                wxpayServiceRp.setResult_msg(map.get("err_code").toString());
                wxpayServiceRp.setResult_code("0001");
            }

        } catch (Exception e) {
            wxpayServiceRp.setResult_code("0100");
            wxpayServiceRp.setResult_msg("等待处理中");
        }
        log.info("微信支付返回参数=Result_code={}，Result_msg={}，out_trade_no={}", wxpayServiceRp.getResult_code(), wxpayServiceRp.getResult_msg(), out_trade_no);
        return wxpayServiceRp;
    }

    @Override
    public WxpayServiceRp querydfOrder(String out_trade_no) throws Exception {
        WxpayServiceRp wxpayServiceRp = new WxpayServiceRp();
        try {
            // ip地址获取
            // 账号信息
            String currTime = PayCommonUtil.getCurrTime();
            String strTime = currTime.substring(8, currTime.length());
            String strRandom = PayCommonUtil.buildRandom(4) + "";
            String nonce_str = strTime + strRandom;
            // 价格 注意：价格的单位是分

            // 设置package订单参数
            SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
            packageParams.put("mch_appid", APP_ID);
            packageParams.put("mchid", MCH_ID);
            // 生成签名的时候需要你自己设置随机字符串
            packageParams.put("nonce_str", nonce_str);
            packageParams.put("partner_trade_no", out_trade_no);

            String sign = PayCommonUtil.createSign("UTF-8", packageParams, APP_KEY);
            packageParams.put("sign", sign);
            log.info("微信支付请求参数=appid={}，mch_id={}，nonce_str={}，out_trade_no={} ,sign={}", APP_ID, MCH_ID, nonce_str, out_trade_no, sign);
            String requestXML = PayCommonUtil.getRequestXml(packageParams);
            log.info("微信支付请求参数=requestXML=[{}]", requestXML);
            String resXml = HttpUtil.postData(DF_QUERY_URL, requestXML);
            log.info("微信支付返回参数=resXml=[{}]", resXml);

            Map map = XMLUtil.doXMLParse(resXml);
            if (StringUtils.isNotEmpty(map.get("return_code").toString()) && map.get("return_code").toString().equals("SUCCESS")) {
                if (StringUtils.isNotEmpty(map.get("status").toString()) && map.get("status").toString().equals("SUCCESS")) {
                    wxpayServiceRp.setResult_msg("转账成功");
                    wxpayServiceRp.setResult_code("0000");
                } else if (StringUtils.isNotEmpty(map.get("status").toString()) && map.get("status").toString().equals("FAILED")) {
                    wxpayServiceRp.setResult_msg("转账失败");
                    if (StringUtils.isNotBlank(map.get("return_msg").toString())) {
                        wxpayServiceRp.setResult_msg(map.get("return_msg").toString());
                    }
                    wxpayServiceRp.setResult_code("0001");
                    //wxpayServiceRp.setErr_code_des(map.get("reason").toString());
                } else {
                    wxpayServiceRp.setResult_msg("处理中");
                    wxpayServiceRp.setResult_code("0100");
                }
            } else {
                wxpayServiceRp.setResult_msg(map.get("return_msg").toString());
                wxpayServiceRp.setResult_code("0100");
            }

        } catch (Exception e) {
            wxpayServiceRp.setResult_code("0100");
            wxpayServiceRp.setResult_msg("等待处理中");
        }
        log.info("微信支付查询返回参数=Result_code={}，Result_msg={}，out_trade_no={}", wxpayServiceRp.getResult_code(), wxpayServiceRp.getResult_msg(), out_trade_no);
        return wxpayServiceRp;

    }


}
